iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 15
0
AI & Data

看圖說故事,讓 Neo4j 重新詮釋你的資料庫系列 第 15

Neo4j 資料庫索引與約束

  • 分享至 

  • xImage
  •  

前面幾篇文章介紹了 Neo4j Bloom 探索資料庫的方式,但如果你的資料庫很大,可能會速度開始變慢,或是 Bloom 只顯示一部分的節點資料,而沒有全部。
這其實是 Bloom 為了效能上的考量,當回傳資料量太大時,會限制輸出,畢竟它只是方便我們觀察與探索資料特性,而不是要視覺上完全呈現所有查詢結果。

另外,對於 1000 個節點以內的小資料庫,Bloom 搜尋時會試著掃描所有節點的屬性,遇到更大的資料庫,Bloom 就會試著去找索引來大幅提升查詢效率。當然你還是可以明確指定標籤、屬性和關係,無論是在 Neo4j Bloom 或 Neo4j Browser。

今天要分享的就是,如何建立索引,就好比關聯式資料庫的索引,針對某個欄位(圖資料庫的屬性)建立索引,將大幅提升以該欄位/屬性查詢的效率。代價是會使用更多的儲存空間。

建立索引(Index)

在 Customer 標籤的 companyName 屬性建立索引

CREATE INDEX ON :Customer(companyName)

之後以該屬性 companyName 查詢客戶時,就會自動使用索引,以下是幾種常見的使用方式:

MATCH (c:Customer) WHERE c.companyName = 'Wartian Herkku'
RETURN c
MATCH (c:Customer { companyName: 'Wartian Herkku' })
RETURN c
MATCH (c:Customer) WHERE c.companyName > 'W'
RETURN c
MATCH (c:Customer) WHERE c.companyName IN ['Wartian Herkku', 'Maison Dewey']
RETURN c
MATCH (c:Customer) WHERE c.companyName STARTS WITH 'War'
RETURN c
MATCH (c:Customer) WHERE exists(c.companyName)
RETURN c

特別注意的是,如果屬性經過運算,就不會使用索引,這點跟關聯式資料庫也是一樣的。

MATCH (c:Customer) WHERE lower(c.companyName) = 'wartian herkku'
RETURN c

如果是很長一串的複雜 Cypher 查詢,沒有把握索引會自動使用,也可以明確指定使用索引

MATCH (c:Customer)
USING INDEX c:Customer(companyName)
WHERE c.companyName = 'Wartian Herkku'
RETURN c

刪除索引。如果屬性值重複率很高,或是非常少被查詢,那麼建立索引的效果可能不大,可以考慮刪除。

DROP INDEX ON :Customer(companyName)

除了在標籤屬性建立索引之外,也可以對關係的屬性建立索引

CREATE INDEX ON :ORDERS(productID)
DROP INDEX ON :ORDERS(productID)

建立約束(Constraint)

如果希望確保某個屬性值是唯一,避免在新增或修改資料時產生重複,就可以建立約束;建立約束時將同時建立索引,所以也能提升查詢效率。
不過約束不代表所有節點都必須有該屬性,約束有分唯一性約束存在性約束,後者才能確保所有節點擁有某個屬性。

建立 Customer.phone 的唯一性,亦即是,所有客戶的電話不應重複。建立唯一性約束前,要先確保該屬性目前沒有任何重複的值,否則會建立失敗!

CREATE CONSTRAINT ON (c:Customer)
ASSERT c.phone IS UNIQUE

刪除節點屬性的唯一性約束

DROP CONSTRAINT ON (c:Customer)
ASSERT c.phone IS UNIQUE

建立 Customer.phone 的存在性約束,亦即是,新增客戶資料時,不能省略電話,否則將新增失敗!
建立存在性約束前,要先確保所有節點都已有該屬性值,否則會建立失敗!

CREATE CONSTRAINT ON (c:Customer)
ASSERT exists(c.phone)

刪除節點屬性的唯一性約束

DROP CONSTRAINT ON (c:Customer)
ASSERT exists(c.phone)

除了節點屬性之外,關係的屬性也可以建立約束喔!
以下確保每一筆訂單都有填寫 productID

CREATE CONSTRAINT ON ()-[o:ORDERS]->()
ASSERT exists(o.productID)

刪除關係屬性的存在性約束

DROP CONSTRAINT ON ()-[o:ORDERS]->()
ASSERT exists(o.productID)

以上是今天的分享,在大型資料庫中索引與約束相當的重要,下次將繼續延伸這些內容,還請大家繼續支持:)

參考來源:
https://medium.com/neo4j/tips-and-tricks-in-neo4j-bloom-41e4b3b1cc8f


上一篇
Neo4j Bloom 自然語言搜尋與自訂樣式
下一篇
Neo4j 資料庫查詢效能優化 - 執行計畫
系列文
看圖說故事,讓 Neo4j 重新詮釋你的資料庫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言